/*
 * 
 */
package org.opu.gui.docviewer;

import doc2db.interfaces.action.open.JEditPContentMenu;
import java.io.IOException;
import java.awt.Color;
import java.awt.Cursor;
import javax.swing.JPopupMenu;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.JEditorPane;
import javax.swing.text.StyleContext;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.Ffn;
import org.apache.poi.hwpf.model.FontTable;
import org.apache.poi.hwpf.model.StyleDescription;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.CharacterProperties;
import org.apache.poi.hwpf.usermodel.ParagraphProperties;

/**
 *
 * @author yura
 */
public class DocUTIL {
    /** Writing a word with its first letter as a majuscule (upper-case letter).
     * <b>Boolean properties</b>*/
    public static final String PROPERTY_CAPITALIZED = "doc.charrun.capitalized";

    /** Writing a word with a 2 horizontal line through the center of them.
     * <b>Boolean properties</b>*/
    public static final String PROPERTY_DOUBLE_STRIKE = "doc.charrun.doublestrikethrough";

    /** Text appears to be lifted off the page, with shadowing at the edges.
     * <b>Boolean properties</b> */
    public static final String PROPERTY_EMBOSSED = "doc.charrun.embossed";

    /** Writing a word with a special background collor.
     * <b>Boolean properties</b> */
    public static final String PROPERTY_HIGHLIGHTED = "doc.charrun.highlighted";

    /** Puts the characters lower down than regular text if it positive value,
     * and puts the characters higher up than regular text if it negative.
     * <b>Integer properties</b> */
    public static final String PROPERTY_SUB_INDEX = "doc.charrun.subsuperscriptindex";

    /** <b>Boolean properties</b> */
    public static final String PROPERTY_VANISHED = "doc.charrun.vanished";

    /**
     *  Create style context from hwpf style shet and hwpf font table
     *
     * @param word word document
     * @see StyleSheet
     * @see FontTable
     * @return style context from hwpf style shet and hwpf font table
     */
    public static StyleContext getStyleSheet(HWPFDocument word) {
        StyleSheet styleSheet = word.getStyleSheet();
        StyleContext styles = new StyleContext();
        int numStyles = styleSheet.numStyles();
        for (int i = 0; i < numStyles; i++) {
            StyleDescription stlDescr = styleSheet.getStyleDescription(i);
            if (stlDescr == null){
                continue;
            }

            String name = stlDescr.getName();
            ParagraphProperties parStl = stlDescr.getPAP();
            CharacterProperties chrStl = stlDescr.getCHP();
            int baseId = stlDescr.getBaseStyle();

            Style style;
            if (baseId < numStyles) {
                StyleDescription parentStl = styleSheet.getStyleDescription(baseId);
                String parentName = parentStl.getName();
                style = styles.addStyle(name, styles.getStyle(parentName));
            } else {
                style = styles.addStyle(name, null);
            }


            if (chrStl != null) {
                short s = chrStl.getSubSuperScriptIndex();
                StyleConstants.setBackground(style, Color.white);
                StyleConstants.setBold(style, chrStl.isBold());
                StyleConstants.setFontFamily(style,
                        word.getRange()
                        .getParagraph(styleIndex(i, word))
                        .getCharacterRun(0)
                        .getFontName());
                StyleConstants.setFontSize(style, ptFontSize(chrStl.getFontSize()));
                StyleConstants.setForeground(style, decodColor(chrStl.getColor()));
                StyleConstants.setItalic(style, chrStl.isItalic());
                StyleConstants.setStrikeThrough(style, chrStl.isStrikeThrough());
                StyleConstants.setSubscript(style, s > 0);
                StyleConstants.setSuperscript(style, s < 0);
                StyleConstants.setUnderline(style, chrStl.getUnderlineCode() > 0);
            }
            if (parStl != null) {
                StyleConstants.setAlignment(style, parStl.getFontAlignment());
                StyleConstants.setFirstLineIndent(style, parStl.getFirstLineIndent());
                StyleConstants.setLeftIndent(style, codeToFloat(parStl.getLeftBorder().toInt()));
                StyleConstants.setLineSpacing(style, codeToFloat(parStl.getLineSpacing().toInt()));
                StyleConstants.setRightIndent(style, codeToFloat(parStl.getRightBorder().toInt()));
                StyleConstants.setSpaceAbove(style, parStl.getSpacingBefore());
                StyleConstants.setSpaceBelow(style, parStl.getSpacingAfter());
            }
        }

        //System.out.println(styles);
        return styles;
    }


    /**
     *  If you now style index, and you need first instantion of paragraph
     * you call this method and it returneded index of paragraph. 0 can
     * be paragraph index or default value if now such paragraph
     * @param value style index in StyleSheet
     * @param word document where data founding
     * @return first instantion of paragraph with style index value
     * @see StyleSheet
     * @see Paragraph
     */
    public static int styleIndex(int value, HWPFDocument word){
        Range ranges = word.getRange();

        try {
            for (int i = 0; i < ranges.numParagraphs(); i++) {
                if (ranges.getParagraph(i).getStyleIndex() == value) {
                    return i;
                }
            }
        } catch (Exception e) {
            System.err.println(DocUTIL.class.getClass() + " - can get style index " + e);
        }

        return 0;
    }

    /**
     *  Map character run defined font size to HTML font size attribute:
     * <ul>
     *  <li>note input font size is twice the user specified font size (so it is an int I guess)</li>
     *  <li>to determine mapping below, mimic word export to html</li>
     * </ul>
     *   pt size, 2*pt size html size
     * <pre>
     *      6       12          1
     *      8       16          1
     *      10      20          2
     *      12      24          3
     *      14      28          4
     *      16      32          4
     *      18      36          5
     *      20      40          5
     *      24      48          6
     *      28      56          6
     *      32      64          7
     *      36      72          7
     * </pre>
     * @param size pt*2 size
     * @return hmlt size
     */
    public static int htmlFontSize(int size) {
        //if (true) return size;
        if (size < 10) {
            return 1;
        } else if (size < 24) {
            return 2;
        } else if (size < 28) {
            return 3;
        } else if (size < 36) {
            return 4;
        } else if (size < 48) {
            return 5;
        } else if (size < 64) {
            return 6;
        }
        return 7;
    }

    /**
     *  Return size delim on 2 (size in clean pt)
     *
     * @see DocUTIL#htmlFontSize(int) 
     * @param size  pt*2 size
     * @return pt size
     */
    public static int ptFontSize(int size){
        return size/2;
    }

    /**
     *  Get the CHP record ico field.
     * @param index ico field
     * @return CHP record
     */
    public static Color decodColor(int index){
        return new Color(index);
    }

    /**
     * decode border code to float value
     * @param code border code
     * @return decode border code to float value
     */
    public static float codeToFloat(int code){

        if (code <= 0){
            return 0;
        }

        Float f = Float.parseFloat((short) code + "." + (short) (code << 16));

        return f;
    }

    /**
     * Converts a color object to its hex value. The hex value
     * prefixed is with `#', for example `#ff0088'.
     * @param c The color object
     */
    public static String getColorHexString(Color c) {
        String colString = Integer.toHexString(c.getRGB() & 0xffffff);
        int cleraColStrLen = 7 - colString.length();
        String startOfColStr = "#000000".substring(0, cleraColStrLen);
        String rightColStr = startOfColStr.concat(colString);
        return rightColStr;
    }
    
    public static JEditorPane getDocPane(String fname) throws IOException{
        DocDocumentReader dr = new DocDocumentReader(fname);
        return getDocPane(dr);
    }

    public static JEditorPane getDocPane(DocDocumentReader dr){
        JEditorPane pane = new JEditorPane();
        dr.parseDocument();

        pane.setEditorKit(dr.getStyledEditorKit());
        pane.setDocument(dr.viewDocument(null));
        pane.setEditable(false);
        pane.setCursor(new Cursor(Cursor.TEXT_CURSOR));

        JPopupMenu editmn = new JEditPContentMenu(null).getLynkSelectPaneMenu(pane);
        pane.setComponentPopupMenu(editmn);

        return pane;
    }
}
